package br.com.fiap.fiappizzas.dao;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import br.com.fiap.fiappizzas.db.entities.Entity;
import br.com.fiap.fiappizzas.db.helper.FiapSQLittleHelper;

public abstract class AbstractDAO<T extends Entity> {
	
	private FiapSQLittleHelper sqlHelper;
	
	public AbstractDAO(Context context) {
		this.sqlHelper = new FiapSQLittleHelper(context);
	}
	
	public T insert(T entity) {
		
		Log.d("insert ", entity.toString()); 
		 
		SQLiteDatabase db = null;
		try {
			 db = getWritableDB();
		}catch(Throwable e) {
			e.printStackTrace();
		}
 
        ContentValues values = buildContentValues(entity);
        
        long id = 0;
        try {
        	 id = db.insert(getTableName(), // table
                     null, //nullColumnHack
                     values); // key/value -> keys = column names/ values = column values
		}catch(Throwable e) {
			e.printStackTrace();
		}

        db.close();
        
        return getEntityById(id);
		
	}
	
	public void delete(T entity) {

		final SQLiteDatabase db = getWritableDB();
 
        db.delete(getTableName(), //table name
                "id = ?",  // selections
                new String[] { String.valueOf(entity.getId()) }); //selections args
 
        db.close();
 
        Log.d("delete ", entity.toString());
        
	}

	public T update(T entity) {
		
	    final SQLiteDatabase db = getWritableDB();
	 
	    ContentValues values = buildContentValues((T)entity);
	 
	    db.update(getTableName(), //table
	            values, // column/value
	            "id = ?", // selections
	            new String[] { String.valueOf(entity.getId()) }); 
	 
	    // 4. close
	    db.close();
	 
	    return getEntityById(entity.getId());
		
	}
	
	public T getEntityById(Long id) {
		
		final SQLiteDatabase db = getReadableDB();
		
		Cursor cursor = 
	            db.query(getTableName(), // a. table
	            getColumns(), // b. column names
	            " id = ?", // c. selections 
	            new String[] { String.valueOf(id) }, // d. selections args
	            null, // e. group by
	            null, // f. having
	            null, // g. order by
	            null); // h. limit
	 
	    // 3. if we got results get the first one
	    if (cursor != null && cursor.getCount() != 0) {
	    	cursor.moveToFirst();
	    	T entity = buildEntity(cursor);
	    	
	    	Log.d("getEntityById("+id+")", entity.toString());
	    	
	    	return entity;
	    }
	 
	    return null;
				
	}
	
	public List<T> findAll() {
		
		final SQLiteDatabase db = getReadableDB();
		
		Cursor cursor = 
	            db.query(getTableName(), // a. table
	            getColumns(), // b. column names
	            null, // c. selections 
	            null, // d. selections args
	            null, // e. group by
	            null, // f. having
	            null, // g. order by
	            null); // h. limit
		
		if (cursor != null) cursor.moveToFirst();
		
		final List<T> entities = new ArrayList<T>(cursor.getCount());
		
		while (cursor.moveToNext()) {
			entities.add(buildEntity(cursor));
		}
		
		return entities;
	}

	public abstract String getTableName();
	public abstract String[] getColumns();
	public abstract T buildEntity(Cursor cursor);
	public abstract ContentValues buildContentValues(T entity);
	
	protected final SQLiteDatabase getWritableDB() {
		return sqlHelper.getWritableDatabase();
	}
	
	protected final SQLiteDatabase getReadableDB() {
		return sqlHelper.getReadableDatabase();
	}

}
